//<%@ taglib prefix="jj" uri="http://jaxson.org/base" %>

//<jj:import>
org.jaxson.Observable;
org.jaxson.util.http.XHR;
//</jj:import>

namespace( "org.jaxson.util.http");
org.jaxson.util.http.JsonServiceClient = function(config){
	
	var lager = new Logger( "org.jaxson.util.http.JsonServiceClient", Logger.LEVEL_DEBUG );
	function Handler(event, instance){
		return { 
			event : event,
			handle : function(params){
				that.txRequest(event.url, event.basename, params, instance);
			}
		};
	}

	var that = {
		txRequest : function(url, evtname, params, source){
			var evt = {url: url, params: params, source: source};
			evt.name = evtname + ".attempt";
			
			var doit = EventDispatcher.fire( evt );
			
			if( doit === false )
				return;
			
			var xhr = org.jaxson.util.http.XHR();
			xhr.setRequestParameters(params);
			xhr.setMethod("POST");
			xhr.doRequest(url);
			
			evt.xhr = xhr;
			
			xhr.onerror = function(){
				evt.name = evtname + ".failed";
				evt.statusCode = xhr.getStatusCode();
				lager.debug( "service failure: xhr error", evt );
				EventDispatcher.fire( evt );
			};
			
			xhr.onsuccess = function(){
				var response = xhr.getResponseText();
				evt.statusCode = xhr.getStatusCode();
				
				if( response === undefined || response === null || response.trim().length === 0 ){
					return;
				}
				var result = {response: response};
				
				// TODO: fix this.
				//if( xhr.getResponseHeaders()["Content-Type"] === "application/json" )
				
				try{
					eval( "result = {response: " + response + "}");
				}
				catch( e ){
					lager.error( e );
				}
				
				if( result === null || result === undefined ){
					return;
				}
				evt.response = result.response;
				
				if( result.response.errors && result.response.errors.length > 0 ){
					evt.name = evtname + ".failed";
					EventDispatcher.fire( evt );
					lager.debug( "service failure: action returned errors", evt );
					return;
				}
				
				evt.name = evtname + ".succeeded";
				lager.debug( "service success", evt );
				EventDispatcher.fire( evt );
			};
			
			evt.name = evtname + ".attempted";
			EventDispatcher.fire( {name: evtname + ".attempted", params: params, url: url, xhr: xhr} );
		},
		
		createBindings : function(instance){
			var evts = instance.getEvents();
			
			for( i=0; i<evts.length; i++ ){
				
				if( !evts[i].tx )
					continue;
				
				var tokens = evts[i].basename.split(".");
				var method = "";
				for( j in tokens ){
					if( j == 0 )
						method = tokens[j];
					else{
						method += tokens[j].charAt(0).toUpperCase() + tokens[j].substring(1);
					}
				}
				
				if( !instance[method] ){
					var wrapper = new Handler( evts[i], that );
					instance[method] = wrapper.handle;
				}
				
				i = i+3;
			}
			
			return instance;
		}
	};
	
	inherits( "org.jaxson.Observable", "org.jaxson.util.http.JsonServiceClient", that, config );
	
	return that;
}